import ply.yacc as yacc
from cal import tokens

ids={}
flag=1

class Node:
    def __init__(self,type,children=None):
         self.type = type
         if children:
              self.children = children
         else:
              self.children = [ ]
    


def p_function_main(p):
    '''function : VOID MAIN "(" ")" vardefines "{"  multiexpression "}"  '''
    # for i in range(len(p)):
    #      print('p_statement_main', 'pos', i, 'value', p[i])

def p_function_pp(p):
    '''function : vardefines '''

def p_function_assign(p):
    'function : INT ID "=" expression'
    ids[p[2]]=p[4]
    print(p[2][1])
    # print(p.value[4])
    # for i in range(len(p)):
    #      print('p_statement_assign', 'pos', i, 'value', p[i])

#----------------------函数声明部分-------------
def p_tid(p):
    ''' tid : INT
            | FLOAT
            | CHAR '''
    p[0]=p[1]

def p_dh_tint(p):
    'dh : INT identifier '

def p_wfd(p):
    '''wfd : dh "(" parameter ")" "{" multiexpression "}" '''

def p_parameter_yige(p):
    'parameter : tid identifier '

def p_parameter_duoge(p):
    'parameter : tid identifier  parameter'

#-----------变量声明---------------

def p_vardefine_dange(p):
    'vardefine : tid identifier ";"'
    if(p[1]=='int'):
        ids[p[2]]=0
    elif(p[1]=='char'):
        ids[p[2]]=' '
    else:
        ids[p[2]]=0.0

def p_vardefine_duoge(p):
    'vardefine : tid identifier "[" NUMBER "]" ";"'
    if(p[1]=='int'):
        ids[p[2]]=[0]
    elif(p[1]=='char'):
        ids[p[2]]=[' ']
    else:
        ids[p[2]]=[0.0]

def p_vardefines(p):
    '''vardefines : vardefine 
                  | vardefine  vardefines 
                  |'''

#------------------------------------------

def p_multiexpression_a(p):
    '''multiexpression : statements'''
    # for i in range(len(p)):
    #      print('p_multiexpression_a', 'pos', i, 'value', p[i])
#-----------------------各种statement-------------------------
def statements(p):
    if(len(p.children)==1):
        statement(p.children[0])
    else: 
        statement(p.children[0])
        statements(p.children[1])

def p_statements(p):
    ''' statements : statement  
                   | statement statements'''
    if(len(p)>2):
        p[0]=Node('statements',[p[1],p[2]])
    else:
        p[0]=Node('statements',p[1])
    statements(p[0])
    

def p_statement_ifstate(p):
    'statement : IF "(" condition ")" statement'
    p[0]=Node('if',[p[3],p[5]])

    # if(p[3]):
    #     print('if right')
    # else:
    #     flag=0
    #     print('if wrong')

    # for i in range(len(p)):
    #      print('p_statement_ifstate', 'pos', i, 'value', p[i])

#------------------------
def p_condition(p):
    '''condition : expression ro expression
                 | expression '''
    
    if(len(p)>2):
        if(p[2]=='=='):
            temp=(p[1]==p[3])
        elif(p[2]=='>'):
            temp=(p[1]>p[3])
        elif(p[2]=='<'):
            temp=(p[1]<p[3])
    p[0]=Node('condition',temp)
        
        

#----------------------------------------

def p_statement_whilestate(p):
    '''statement : WHILE "(" condition ")" statement  '''

# def p_statement_statements(p):
#     ' statement : statements  '

def assign(p):
    if(ids.__contains__(p[0])):
        if(len(p)>5):
            if(len(ids[p[0]]) > p[1] ):
                ids[p[0]][p[1]]=p[2]
            else: 
                ids[p[0]].append(p[2])
        else:
            ids[p[0]]=p[1]
            print(p[1],'as')
    else:
        print("you have not define",p[1])

def p_statement_assignstate(p):
    '''statement :  identifier "=" expression ';'
                 |  identifier "[" expression "]" "=" expression ';' '''
    if(len(p)>5):
        p[0]=Node('assignarray',[p[1],p[3],p[6]])
    else:
        p[0]=Node('assign',[p[1],p[3]])
    
  


    
    # for i in range(len(p)):
    #      print('p_statement_assignstate', 'pos', i, 'value', p[i])

def p_statement_read(p):
    '''statement : SCANF '(' identifier ')' '''

# def p_statement_write(p):
#     'statement :  '

#-------------switch-------------

# def p_statement_switch(p):
#     'statement : switch "(" expression ")" ctable default'

# def p_ctable_yige(p):
#     'ctable : case NUMBER ":" statement '

#-----------------------------


                
def p_ro(p):
    '''ro : LESS
          | ELESS
          | MORE
          | EMORE
          | EQ
          | UEQ'''
#--------------------基础部件------------------------------
def p_expression(p):
    '''expression : expression "+" term
                  | expression "-" term
                  | term     '''
    if(len(p)>3):
        print('p[2]exist')
        print(p[1],p[3])
        if(p[2]=='+'):
            p[0]=p[1]+p[3]
            print('expression',p[0])
        else:
            p[0]=p[1]=p[3]
            print('expression',p[0])
    else:
        p[0]=p[1]
    # for i in range(len(p)):
    #      print('p_expression', 'pos', i, 'value', p[i])
def p_term(p):
    '''term : term "*" factor
            | term "/" factor
            | factor '''
    if(len(p)>3):
        print(len(p))
        if(p[2]=='*'):
            p[0]=p[1]*p[3]
            print('term',p[0])
        else:
            p[0]=p[1]/p[3]
            print('term',p[0])
    else:
        p[0]=p[1]
    # for i in range(len(p)):
    #      print('p_term', 'pos', i, 'value', p[i])
def p_factor(p):
    '''factor : NUMBER
              | "(" expression ")"
              | identifier
              | ID'''
    if(p[1]=='('):
        print('factor',p[2])
        p[0]=p[2]
    else:
        print('factor',p[1])
        p[0]=p[1]


# def p_factor_identifier(p):
#     'factor : identifier "[" expression "]"'
#     p[0]=ids


    # for i in range(len(p)):
    #      print('p_factor', 'pos', i, 'value', p[i])

def p_identifier(p):
    ''' identifier : ID'''
                #    | ID identifier
                #    | NUMBER identifier 
                #    | NUMBER
    # if(len(p)>2):
    #     p[0]=str(p[1])+str(p[2])
    #     print(p[0],'id1')
    # # else:
    p[0]=str(p[1])
    print(p[0],'id')

    # for i in range(len(p)):
    #      print('p_identifier', 'pos', i, 'value', p[i])
#-------------------------------------------------------

# Error rule for syntax errors
def p_error(p):
    print("Syntax error in input!")


parser = yacc.yacc()
 
while True:
    try:
        s = input('calc > ')
    except EOFError:
        break
    if not s: continue
    result = parser.parse(s)
    print(result)